package ua.yandex.prodcons.utilconcurrent;

import java.util.concurrent.locks.*;

public class CircularBuffer {
// Тут remove и add , то есть коллекция модифицируется . Если добавлять метод,
    // то использывать еще один обьект condition или убирать condition и 
    // использывать readLock writeLock;

    private String[] elements;
    private int head;
    private int tail;
    private int size;
    private int capacity;
    private Lock aLock = new ReentrantLock();
    private Condition aCondVar = aLock.newCondition();

    public CircularBuffer(int capacity) {
        this.elements = new String[capacity];
        for (int i = 0; i < capacity; i++) {
            elements[i] = " ";
        }
        this.capacity = capacity;
    }

    public void add(String data) {
        aLock.lock();
        try {
            while (size == elements.length) {
                try {
                    aCondVar.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            elements[tail] = data;
            size++;
            tail = (tail + 1) % capacity;
            aCondVar.signalAll();
        } finally {
            aLock.unlock();
        }
    }

    public String remove() throws InterruptedException {
        aLock.lock();
        String res = new String();
        try {
            while (size == 0) {
                try {
                    aCondVar.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            res = elements[head];
            head = (head + 1) % capacity;
            size--;
            aCondVar.signalAll();
        } finally {
            aLock.unlock();
            return res;
        }
    }
}
